package com.example.demo.utils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

public class GsonUtils {

  private GsonUtils() {

  }

  private static Gson gsonInstance = null;

  static {
    gsonInstance = new GsonBuilder()
        .registerTypeAdapter(
            new TypeToken<TreeMap<String, Object>>() {
            }.getType(),
            new JsonDeserializer<TreeMap<String, Object>>() {
              @Override
              public TreeMap<String, Object> deserialize(
                  JsonElement json, Type typeOfT,
                  JsonDeserializationContext context) throws JsonParseException {

                TreeMap<String, Object> treeMap = new TreeMap<>();
                JsonObject jsonObject = json.getAsJsonObject();
                Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
                for (Map.Entry<String, JsonElement> entry : entrySet) {
                  treeMap.put(entry.getKey(), entry.getValue());
                }
                return treeMap;
              }
            }).create();
  }

  public static String toJson(Object o) {
    Gson gson = new Gson();
    return gson.toJson(o);

  }

  public static <T> T fromJson(String json, Class<T> type) {
    Gson gson = new Gson();
    return gsonInstance.fromJson(json, type);

  }

  public static <T> List<T> listFromJson(String json) {
    Gson gson = new Gson();
    return gson.fromJson(json, new TypeToken<List<T>>() {
    }.getType());
  }

  public static <T> List<T> listFromJson(String json, Class<T> type) {
    ArrayList<T> list = new ArrayList<>();
    JsonArray jsonArray = new JsonParser().parse(json).getAsJsonArray();
    for (JsonElement e : jsonArray) {
      list.add(new Gson().fromJson(e, type));
    }
    return list;
  }

}